package com.icen.utils.comm;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import android.content.Context;

/**
 * File Utils Class
 * 
 * @author IcenHan
 * 
 */
public class FileUtils {

	/**
	 * 获取文件的大小
	 * 
	 * @param filePath
	 *            文件路径
	 * @return long
	 * 
	 */
	public static long getFileSize(String filePath) {
		if (ValidateUtils.isBlank(filePath)) {
			return -1;
		}

		File file = new File(filePath);
		return (file.exists() && file.isFile() ? file.length() : -1);
	}

	/**
	 * 判断文件是否存在
	 * 
	 * @param filePath
	 *            文件路径
	 * @return boolean
	 */
	public static boolean isFileExist(String filePath) {
		if (ValidateUtils.isBlank(filePath)) {
			return false;
		}

		File file = new File(filePath);
		return (file.exists() && file.isFile());
	}

	/**
	 * 判断文件夹是否存在
	 * 
	 * @param dirPath
	 *            目录
	 * @return boolean
	 */
	public static boolean isFolderExist(String dirPath) {
		if (ValidateUtils.isBlank(dirPath)) {
			return false;
		}

		File dire = new File(dirPath);
		return (dire.exists() && dire.isDirectory());
	}

	/**
	 * 读取文件到StringBuilder
	 * 
	 * @param filePath
	 *            文件路径
	 * @param charset
	 *            编码格式
	 * @return StringBuilder
	 */
	public static StringBuilder readFile(String filePath, String charset) {
		File file = new File(filePath);
		StringBuilder fileContent = new StringBuilder("");
		if (file == null || !file.isFile()) {
			return null;
		}

		BufferedReader reader = null;
		try {
			InputStreamReader is = new InputStreamReader(new FileInputStream(
					file), charset);
			reader = new BufferedReader(is);
			String line = null;
			while ((line = reader.readLine()) != null) {
				if (!fileContent.toString().equals("")) {
					fileContent.append("\r\n");
				}
				fileContent.append(line);
			}
			reader.close();
			return fileContent;
		} catch (IOException e) {
			throw new RuntimeException("ReadFile", e);
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					throw new RuntimeException("ReadFile", e);
				}
			}
		}
	}

	/**
	 * 读取文件内容到List集合
	 * 
	 * @param filePath
	 *            文件路径
	 * @param charset
	 *            编码集
	 * @return List<String>
	 */
	public static List<String> readFileToList(String filePath, String charset) {
		File file = new File(filePath);
		List<String> fileContent = new ArrayList<String>();
		if (file == null || !file.isFile()) {
			return null;
		}

		BufferedReader reader = null;
		try {
			InputStreamReader is = new InputStreamReader(new FileInputStream(
					file), charset);
			reader = new BufferedReader(is);
			String line = null;
			while ((line = reader.readLine()) != null) {
				fileContent.add(line);
			}
			reader.close();
			return fileContent;
		} catch (IOException e) {
			throw new RuntimeException("ReadFileToList", e);
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					throw new RuntimeException("ReadFileToList", e);
				}
			}
		}
	}

	/**
	 * 将内容写入到文件中
	 * 
	 * @param filePath
	 *            文件路径
	 * @param content
	 *            需要写入的内容
	 * @return boolean
	 */
	public static boolean writeFile(String filePath, String content) {
		return writeFile(filePath, content, false);
	}

	/**
	 * 将内容写入到文件中
	 * 
	 * @param filePath
	 *            文件路径
	 * @param content
	 *            需要写入的内容
	 * @param isAppend
	 *            内容写入方式,ture:覆盖;false:追加
	 * @return boolean
	 */
	public static boolean writeFile(String filePath, String content,
			boolean isAppend) {
		if (ValidateUtils.isEmpty(content)) {
			return false;
		}

		FileWriter fileWriter = null;
		try {
			makeDirs(filePath);
			fileWriter = new FileWriter(filePath, isAppend);
			fileWriter.write(content);
			fileWriter.close();
			return true;
		} catch (IOException e) {
			throw new RuntimeException("ReadFile", e);
		} finally {
			if (fileWriter != null) {
				try {
					fileWriter.close();
				} catch (IOException e) {
					throw new RuntimeException("ReadFile", e);
				}
			}
		}
	}

	/**
	 * 将List集合中的内容写入到文件中
	 * 
	 * @param filePath
	 *            文件路径
	 * @param strList
	 *            内容List集合
	 * @return boolean
	 */
	public static boolean writeFile(String filePath, List<String> strList) {
		return writeFile(filePath, strList, false);
	}

	/**
	 * 将List集合中的内容写入到文件中
	 * 
	 * @param filePath
	 *            文件路径
	 * @param strList
	 *            内容List集合
	 * @param isAppend
	 *            内容写入方式,ture:覆盖;false:最佳
	 * @return boolean
	 */
	public static boolean writeFile(String filePath, List<String> strList,
			boolean isAppend) {
		if (ValidateUtils.isEmpty(strList)) {
			return false;
		}

		FileWriter fileWriter = null;
		try {
			makeDirs(filePath);
			fileWriter = new FileWriter(filePath, isAppend);
			int i = 0;
			for (String line : strList) {
				if (i++ > 0) {
					fileWriter.write("\r\n");
				}
				fileWriter.write(line);
			}
			fileWriter.close();
			return true;
		} catch (IOException e) {
			throw new RuntimeException("IOException occurred. ", e);
		} finally {
			if (fileWriter != null) {
				try {
					fileWriter.close();
				} catch (IOException e) {
					throw new RuntimeException("IOException occurred. ", e);
				}
			}
		}
	}

	public static boolean writeFile(String filePath, InputStream stream) {
		return writeFile(filePath, stream, false);
	}

	public static boolean writeFile(String filePath, InputStream stream,
			boolean append) {
		return writeFile(filePath != null ? new File(filePath) : null, stream,
				append);
	}

	public static boolean writeFile(File file, InputStream stream) {
		return writeFile(file, stream, false);
	}

	public static boolean writeFile(File file, InputStream stream,
			boolean append) {
		OutputStream o = null;
		try {
			makeDirs(file.getAbsolutePath());
			o = new FileOutputStream(file, append);
			byte data[] = new byte[1024];
			int length = -1;
			while ((length = stream.read(data)) != -1) {
				o.write(data, 0, length);
			}
			o.flush();
			return true;
		} catch (FileNotFoundException e) {
			throw new RuntimeException("FileNotFoundException occurred. ", e);
		} catch (IOException e) {
			throw new RuntimeException("IOException occurred. ", e);
		} finally {
			if (o != null) {
				try {
					o.close();
					stream.close();
				} catch (IOException e) {
					throw new RuntimeException("IOException occurred. ", e);
				}
			}
		}
	}

	/**
	 * 复制文件
	 * 
	 * @param sourceFilePath
	 *            源文件路径
	 * @param destFilePath
	 *            目标路径
	 * @return boolean
	 */
	public static boolean copyFile(String sourceFilePath, String destFilePath) {
		InputStream inputStream = null;
		try {
			inputStream = new FileInputStream(sourceFilePath);
		} catch (FileNotFoundException e) {
			throw new RuntimeException("FileNotFoundException occurred. ", e);
		}
		return writeFile(destFilePath, inputStream);
	}

	/**
	 * 查找文件夹下所有文件: 递归方式
	 * 
	 * @param strPath
	 * @return List<File>
	 */
	public static List<File> getFileList(String strPath) {
		List<File> filelist = new ArrayList<File>();
		File dir = new File(strPath);
		File[] files = dir.listFiles();
		if (files == null)
			return null;
		for (int i = 0; i < files.length; i++) {
			if (files[i].isDirectory()) {
				getFileList(files[i].getAbsolutePath());
			} else {
				if (files[i].getName().toLowerCase().endsWith("zip"))
					filelist.add(files[i]);
			}
		}
		return filelist;
	}

	/**
	 * 拷贝Assets文件夹下的文件到指定目录
	 * 
	 * @param context
	 * @param assetsFileNmae
	 * @param outDirName
	 * @throws IOException
	 */
	public static void copyAssetsFile(Context context, String assetsFileName,
			String outDirName) throws IOException {
		File outDir = new File(outDirName);
		if (!outDir.exists() || !outDir.isDirectory()) {
			outDir.mkdir();
		}
		File outFile = new File(outDirName + File.separator + assetsFileName);
		if (!outFile.exists()) {
			outFile.createNewFile();
		}
		InputStream is = context.getAssets().open(assetsFileName);
		OutputStream os = new FileOutputStream(outFile);
		byte[] buffer = new byte[1024];
		int length;
		while ((length = is.read(buffer)) > 0) {
			os.write(buffer, 0, length);
		}
		os.flush();
		os.close();
		is.close();
	}

	/**
	 * 查找文件夹下所有文件: 非递归方式
	 * 
	 * @param strPath
	 * @return
	 */
	public static LinkedList<File> getFileLinkedList(String strPath) {
		LinkedList<File> list = new LinkedList<File>();
		File dir = new File(strPath);
		File file[] = dir.listFiles();
		for (int i = 0; i < file.length; i++) {
			if (file[i].isDirectory()) {
				list.add(file[i]);
			}
		}
		File tmp;
		while (!list.isEmpty()) {
			tmp = (File) list.removeFirst();
			if (tmp.isDirectory()) {
				file = tmp.listFiles();
				if (file == null)
					continue;
				for (int i = 0; i < file.length; i++) {
					if (file[i].isDirectory()) {
						list.add(file[i]);
					}
				}
			}
		}
		return list;
	}

	/**
	 * 删除文件
	 * 
	 * @param filePath
	 *            文件路径
	 * @return boolean
	 */
	public static boolean deleteFile(String fileName) {
		File file = new File(fileName);
		return file.exists() ? file.delete() : false;
	}

	/**
	 * 删除目录（文件夹）以及目录下的文件
	 * 
	 * @param dir
	 *            被删除目录的文件路径
	 * @return boolean
	 */
	public static boolean deleteDirectory(String dir) {
		if (!dir.endsWith(File.separator)) {
			dir = dir + File.separator;
		}
		File dirFile = new File(dir);
		if (!dirFile.exists() || !dirFile.isDirectory()) {
			return false;
		}
		boolean flag = true;
		File[] files = dirFile.listFiles();
		for (int i = 0; i < files.length; i++) {
			if (files[i].isFile()) {
				flag = deleteFile(files[i].getAbsolutePath());
				if (!flag) {
					break;
				}
			} else {
				flag = deleteDirectory(files[i].getAbsolutePath());
				if (!flag) {
					break;
				}
			}
		}

		if (!flag) {
			return false;
		}
		if (dirFile.delete()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 创建文件路径
	 * 
	 * @param filePath
	 *            文件路径
	 * @return boolean
	 */
	public static boolean makeDirs(String filePath) {
		String folderName = getFolderName(filePath);
		if (ValidateUtils.isEmpty(folderName)) {
			return false;
		}

		File folder = new File(folderName);
		return (folder.exists() && folder.isDirectory()) ? true : folder
				.mkdirs();
	}

	/**
	 * 创建文件夹
	 * 
	 * @param filePath
	 * @return boolean
	 */
	public static boolean makeFolders(String filePath) {
		return makeDirs(filePath);
	}

	/**
	 * 获取文件名,包含文件后缀
	 * 
	 * @param filePath
	 *            文件路径
	 * @return String
	 */
	public static String getFileName(String filePath) {
		if (ValidateUtils.isEmpty(filePath)) {
			return filePath;
		}

		int filePosi = filePath.lastIndexOf(File.separator);
		return (filePosi == -1) ? filePath : filePath.substring(filePosi + 1);
	}

	/**
	 * 获取文件名,不含文件后缀
	 * 
	 * @param filePath
	 *            文件路径
	 * @return String
	 * 
	 */
	public static String getFileNameWithoutExtension(String filePath) {
		if (ValidateUtils.isEmpty(filePath)) {
			return filePath;
		}

		int extenPosi = filePath.lastIndexOf(".");
		int filePosi = filePath.lastIndexOf(File.separator);
		if (filePosi == -1) {
			return (extenPosi == -1 ? filePath : filePath.substring(0,
					extenPosi));
		}
		if (extenPosi == -1) {
			return filePath.substring(filePosi + 1);
		}
		return (filePosi < extenPosi ? filePath.substring(filePosi + 1,
				extenPosi) : filePath.substring(filePosi + 1));
	}

	/**
	 * 根据URL获取文件的文件名全称
	 * 
	 * @param url
	 *            URL路径
	 * @return String
	 */
	public static String getFileNameOfUrl(String url) {
		if (ValidateUtils.isEmpty(url)) {
			return "";
		}

		int fileNameStart = url.lastIndexOf("/");
		return url.substring(fileNameStart + 1);
	}

	/**
	 * 获取文件夹名字
	 * 
	 * @param filePath
	 *            文件路径
	 * @return String
	 * 
	 */
	public static String getFolderName(String filePath) {

		if (ValidateUtils.isEmpty(filePath)) {
			return filePath;
		}

		int filePosi = filePath.lastIndexOf(File.separator);
		return (filePosi == -1) ? "" : filePath.substring(0, filePosi);
	}

	/**
	 * 获取带有文件后后缀的问卷路径
	 * 
	 * @param filePath
	 *            文件路径
	 * @return String
	 * 
	 */
	public static String getFileExtension(String filePath) {
		if (ValidateUtils.isBlank(filePath)) {
			return filePath;
		}

		int extenPosi = filePath.lastIndexOf(".");
		int filePosi = filePath.lastIndexOf(File.separator);
		if (extenPosi == -1) {
			return "";
		}
		return (filePosi >= extenPosi) ? "" : filePath.substring(extenPosi + 1);
	}

	/***
	 * 获取文件后缀名
	 * 
	 * @param fileName
	 * @return String
	 */
	public static String getFileExt(String fileName) {
		try {
			String[] exts = StringUtils.strToStrArr(fileName, ".");
			return exts[exts.length - 1];
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

}
